package markgame2dphys;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.LinkedList;
import java.util.List;

import javax.swing.JComponent;

import net.phys2d.math.Vector2f;
import net.phys2d.raw.World;

public abstract class MarkGame2DEngine extends JComponent implements Runnable, MouseListener{

	private static final long serialVersionUID = 1L;
	
	private int width;
	private int height;
	
	private World world;
	
	private List<MarkGameObject> objects;
	private List<MarkGameJoint> joints;
	
	private boolean running;
	
	private int fps;
	
	public MarkGame2DEngine(int width, int height, float gravityX, float gravityY, int iterations, int fps) {
		world = new World(new Vector2f(gravityX, gravityY), iterations);
		objects = new LinkedList<MarkGameObject>();
		joints = new LinkedList<MarkGameJoint>();
		this.width = width;
		this.height = height;
		this.fps = fps;
		
		addMouseListener(this);
	}
	
	public final void add(MarkGameObject obj){
		objects.add(obj);
		world.add(obj.body);
	}
	
	public final void add(MarkGameJoint joint){
		joints.add(joint);
		world.add(joint.joint);
	}
	
	public final void stepPhysics(float time){
		world.step(time);
	}
	
	public final void run() {
		running = true;
		long timePerFrame = 1000/fps;
		long last = System.currentTimeMillis();
		while(running){
			long current = System.currentTimeMillis();
			long past = current-last;
			if(past > timePerFrame){
				repaint();
				update(past/1000f);
				last = current;
			}
		}
	}
	
	public final boolean isRunning() {
		return running;
	}

	public final Dimension getSize() {
		return new Dimension(width,height);
	}
	public final Dimension getPreferredSize() {
		return getSize();
	}
	
	public final void paint(Graphics g){
		paint(new MarkGameGraphics((Graphics2D)g));
	}
	
	public abstract void paint(MarkGameGraphics g);
	public void update(float time){
		stepPhysics(time);
	}
	
	public final void paintAllObjects(MarkGameGraphics g){
		for (MarkGameObject obj : objects) {
			obj.paint(g);
		}
	}
	public final void paintAllJoints(MarkGameGraphics g){
		for (MarkGameJoint joint : joints) {
			joint.paint(g);
		}
	}
	
	public void mouseClicked(MouseEvent e) {}
	public void mouseEntered(MouseEvent e) {}
	public void mouseExited(MouseEvent e) {}
	public void mousePressed(MouseEvent e) {}
	public void mouseReleased(MouseEvent e) {}
	
	
}
